package com.lhn.tankGame4;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import java.util.Vector;

/**
 * @author lhn
 * @date 2024-07-24 18:01
 * 坦克大战的绘图区域
 */

public class MyPanel extends JPanel implements KeyListener, Runnable {

    //我的坦克
    Hero play1Hero = null;
    Hero play2Hero = null;


    //定义敌人的坦克，放入Vector
    Vector<EnemyTank> enemyTanks = new Vector<>();
    Vector<Hero> heroes = new Vector<>();
    PlayerAndEnemy playerAndEnemy = new PlayerAndEnemy();

    //当子弹击中坦克时，加入一个Bomb对象到bombVector
    Vector<Bomb> bombVectors = new Vector<>();

    int enemyTankSize = 5;

//    Image image1 = null;
//    Image image2 = null;
//    Image image3 = null;

    //显示我方击毁敌方坦克的信息
    public void showInfo(Graphics g) {

        //画出玩家的成绩
        g.setColor(Color.black);
        Font font = new Font("宋体", Font.BOLD, 20);
        g.setFont(font);

        g.drawString("您累计击毁的地方坦克", 1020, 30);
        drawTank(1020, 60, g, 0, 0);

        g.setColor(Color.black);
        g.drawString(Recorder.getAllEnemyTankCount() + "", 1080, 100);
    }

    public MyPanel(String key){

        switch (key) {
            case "1":
                //初始化玩家坦克
                play1Hero = new Hero(100, 600, 0);
                play2Hero = new Hero(400, 600, 0, 15);

                //初始化敌人坦克
                for (int i = 0; i < enemyTankSize; i++) {
//            enemyTanks.add(new EnemyTank( (150 * ( i + 1) ), 0 ,
//                    new Random().nextInt(4)));
//            enemyTanks.add(new EnemyTank( (150 * ( i + 1) ), 0 ,
//                    2));
//            EnemyTank enemyTank = new EnemyTank( (150 * ( i + 1) ), 0 ,
//                    2);
                    EnemyTank enemyTank = new EnemyTank( (150 * ( i + 1) ), 0 ,
                            new Random().nextInt(3) + 1);
                    enemyTank.setEnemyTanks(enemyTanks);

                    new Thread(enemyTank).start();

                    enemyTanks.add(enemyTank);
                    Shoot shoot = null;

                    switch (
                            enemyTank.getDirection()
                    ) {
                        case 0:
                            shoot = new Shoot(enemyTank.getX() + 20, enemyTank.getY(), enemyTank.getDirection());
                            break;
                        case 1:
                            shoot = new Shoot(enemyTank.getX() + 60, enemyTank.getY() + 20, enemyTank.getDirection());
                            break;
                        case 2:
                            shoot = new Shoot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirection());
                            break;
                        case 3:
                            shoot = new Shoot(enemyTank.getX() + 60, enemyTank.getY() + 20, enemyTank.getDirection());
                            break;
                    }

                    enemyTank.shoots.add(shoot); //发送多颗子弹，将子弹放入集合

                    new Thread(shoot).start();
                }
                break;
            case "2":
                //读取记录
                playerAndEnemy = Recorder.getNodesAndEnemyTankRecord();
                if (playerAndEnemy.getPlayerNode().size() == 1) {
                    //TODO
                    //会出现玩家1（wasd）死亡后保存，玩家2（上下左右）
                    //读档后，玩家2变成玩家1
                    Node node = playerAndEnemy.getPlayerNode().get(0);
                    play2Hero = new Hero(node.getX(), node.getY(), node.getDirection());
                } else {
                    Node node1 = playerAndEnemy.getPlayerNode().get(0);
                    play2Hero = new Hero(node1.getX(), node1.getY(), node1.getDirection());

                    Node node2 = playerAndEnemy.getPlayerNode().get(1);
                    play1Hero = new Hero(node2.getX(), node2.getY(), node2.getDirection());
                }

                //初始化敌人坦克
                for (int i = 0; i < playerAndEnemy.getEnemyNode().size(); i++) {
                    Node node = playerAndEnemy.getEnemyNode().get(i);
                    EnemyTank enemyTank = new EnemyTank( node.getX(), node.getY(), node.getDirection());
                    enemyTank.setEnemyTanks(enemyTanks);

                    new Thread(enemyTank).start();

                    enemyTanks.add(enemyTank);
                    Shoot shoot = null;

                    switch (
                            enemyTank.getDirection()
                    ) {
                        case 0:
                            shoot = new Shoot(enemyTank.getX() + 20, enemyTank.getY(), enemyTank.getDirection());
                            break;
                        case 1:
                            shoot = new Shoot(enemyTank.getX() + 60, enemyTank.getY() + 20, enemyTank.getDirection());
                            break;
                        case 2:
                            shoot = new Shoot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirection());
                            break;
                        case 3:
                            shoot = new Shoot(enemyTank.getX() + 60, enemyTank.getY() + 20, enemyTank.getDirection());
                            break;
                    }

                    enemyTank.shoots.add(shoot); //发送多颗子弹，将子弹放入集合

                    new Thread(shoot).start();
                }

                break;
            default:
                System.out.println("输入有误...");
        }

        Recorder.setEnemyTanks(enemyTanks);
        //TODO
        heroes.add(play2Hero);
        heroes.add(play1Hero);
        Recorder.setHeroes(heroes);



        //初始化图片对象
//        image1 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/Bursts.gif"));
//        image2 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/"));
//        image3 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/"));

    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0, 0, 1000, 750);

        showInfo(g);
        Font defaultFont = new Font("Serif", Font.PLAIN, 12);
        g.setFont(defaultFont);

        if (play1Hero != null && play1Hero.isLive) {
            drawTank(play1Hero.getX(), play1Hero.getY(), g, play1Hero.getDirection(), 1);
        }
        if (play2Hero != null && play2Hero.isLive) {
            drawTank(play2Hero.getX(), play2Hero.getY(), g, play2Hero.getDirection(), 2);
        }

        //player的坐标信息
        g.setColor(Color.RED);
        if (play1Hero != null && play1Hero.isLive) {
            g.drawString(
                    "player1的坐标：(" + play1Hero.getX() + "," + play1Hero.getY() + ")",
                    800, 600);
        }
        if (play2Hero != null && play2Hero.isLive) {
            g.drawString(
                    "player2的坐标：(" + play2Hero.getX() + "," + play2Hero.getY() + ")",
                    800, 620);
        }

        if (play1Hero != null && play1Hero.isLive) {
            //画出play1子弹
            if ((play1Hero.shoot != null) && (play1Hero.shoot.isLive)) {
//            g.setColor(Color.yellow);
//            g.fill3DRect(play1Hero.shoot.getX(), play1Hero.shoot.getY(), 5, 5, false);    //单个子弹
                //player1子弹的坐标信息
//            g.setColor(Color.RED);
//            g.drawString(
//                    "player1子弹的坐标：(" + play1Hero.shoot.getX() + "," + play1Hero.shoot.getY() + ")",
//                    800, 640);
                for (int i = 0; i < play1Hero.shoots.size(); i++) {
                    g.setColor(Color.yellow);
                    Shoot play1Shoot = play1Hero.shoots.get(i);
                    if (play1Shoot != null && play1Shoot.isLive) {
                        g.fill3DRect(play1Shoot.getX(), play1Shoot.getY(), 5, 5, false);
                        g.setColor(Color.red);
                        g.drawString(
                                "player1子弹的坐标：(" + play1Hero.shoots.get(i).getX() + "," + play1Hero.shoots.get(i).getY() + ")",
                                800, 200 + i * 20);
                    } else {
                        //如果该play1Shoot已经无效，就从集合中删除
                        play1Hero.shoots.remove(i);
                    }

                }

            }
        }

        if (play2Hero != null && play2Hero.isLive) {
            //画出play2子弹
            if ((play2Hero.shoot != null) && (play2Hero.shoot.isLive)) {
//            g.setColor(Color.GREEN);
//            g.fill3DRect(play2Hero.shoot.getX(), play2Hero.shoot.getY(), 5, 5, false);
//            //player2子弹的坐标信息
//            g.setColor(Color.RED);
//            g.drawString(
//                    "player2子弹的坐标：(" + play2Hero.shoot.getX() + "," + play2Hero.shoot.getY() + ")",
//                    800, 660);

                for (int i = 0; i < play2Hero.shoots.size(); i++) {
                    g.setColor(Color.green);
                    Shoot play2Shoot = play2Hero.shoots.get(i);
                    if (play2Shoot != null && play2Shoot.isLive) {
                        g.fill3DRect(play2Shoot.getX(), play2Shoot.getY(), 5, 5, false);
                        g.setColor(Color.red);
                        g.drawString(
                                "player2子弹的坐标：(" + play2Hero.shoots.get(i).getX() + "," + play2Hero.shoots.get(i).getY() + ")",
                                800, 300 + i * 20);

                    } else {
                        //如果该play2Shoot已经无效，就从集合中删除
                        play2Hero.shoots.remove(i);
                    }

                }
            }
        }


        //如果bombVector中有对象
//        for (int i = 0; i < bombVectors.size(); i++) {
//            //取出炸弹
//            Bomb bomb = bombVectors.get(i);
//            g.drawImage(image1, bomb.getX(), bomb.getY(), 334, 292, this);
//            bomb.lifeDown();
//            if (bomb.getLife() == 0) {
//                bombVectors.remove(bomb);
//            }
//        }

        //画出敌人坦克和子弹
        EnemyTank enemyTank = null;
        Shoot shoot = null;
        for (int i = 0; i < enemyTanks.size(); i++) {
            enemyTank = enemyTanks.get(i);
            if (enemyTank.isLive) {
                //画出坦克
                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirection(), 0);
                //敌人坦克坐标信息
                g.setColor(Color.white);
                g.drawString(
                        "敌人" + i +"的坐标：(" + enemyTank.getX() + "," + enemyTank.getY() + ")",
                        600, 400 + i * 20);

                //画出子弹
                for (int j = 0; j < enemyTank.shoots.size(); j++) {
                    //取出子弹
                    Shoot shoot1 = enemyTank.shoots.get(j);
                    //绘制
                    if (shoot1.isLive) {
                        g.setColor(Color.cyan);
                        g.draw3DRect(shoot1.getX(), shoot1.getY(), 5, 5, false);
                        //敌人坦克子弹坐标信息
                        g.setColor(Color.white);
                        g.drawString(
                                "敌人" + i + "的子弹的坐标：(" + shoot1.getX() + "," + shoot1.getY() + ")",
                                600, 400 + 20 * enemyTanks.size() + i * 20 + j * 20);
                    } else {
                        //超出边界
                        enemyTank.shoots.remove(shoot1);
                    }
                }
            }

        }

    }

    //画出坦克
    /**
    *
    * @author lihaonan
    * @date 2024/7/26 15:28
     * @param x 坦克的左上角x坐标
     * @param y 坦克的左上角y坐标
     * @param g 画笔
     * @param direction 坦克的方向（上下左右）
     * @param type  坦克类型
    */
    public void drawTank(int x, int y, Graphics g, int direction, int type) {

        //根据不同类型的坦克设置不同的颜色
        g.setColor(Color.RED);
        g.fillOval(x, y, 50, 50);

        switch (
                type
        ) {
            case 0: //敌人使用的坦克
                g.setColor(Color.cyan);
                break;
            case 1: //玩家1
                g.setColor(Color.yellow);
                break;
            case 2:
                g.setColor(Color.GREEN);
                break;
        }

        //根据坦克的方向来绘制坦克
        switch (
                direction
        ) {
            case 0:
                //向上
                g.fill3DRect(x, y, 10, 60, false);
                g.fill3DRect(x + 30, y, 10, 60, false);
                g.fill3DRect(x + 10, y + 10, 20, 40, false);
                g.fill3DRect(x + 10, y + 20, 20, 20, false);
                g.drawLine(x + 20, y + 30, x + 20, y);
                break;
            case 1:
                //向右
                g.fill3DRect(x, y, 60, 10, false);
                g.fill3DRect(x, y + 30, 60, 10, false);
                g.fill3DRect(x + 10, y + 10, 40, 20, false);
                g.fill3DRect(x + 20, y + 10, 20, 20, false);
                g.drawLine(x + 30, y + 20, x + 60, y + 20);
                break;
            case 2:
                //向下
                g.fill3DRect(x, y, 10, 60, false);
                g.fill3DRect(x + 30, y, 10, 60, false);
                g.fill3DRect(x + 10, y + 10, 20, 40, false);
                g.fill3DRect(x + 10, y + 20, 20, 20, false);
                g.drawLine(x + 20, y + 30, x + 20, y + 60 );
                break;
            case 3:
                //向左
                g.fill3DRect(x, y, 60, 10, false);
                g.fill3DRect(x, y + 30, 60, 10, false);
                g.fill3DRect(x + 10, y + 10, 40, 20, false);
                g.fill3DRect(x + 20, y + 10, 20, 20, false);
                g.drawLine(x + 30, y + 20, x, y + 20);
                break;
            default:
                System.out.println("暂时无法处理");
        }
    }

    /**
    *
    * @author lihaonan
    * @date 2024/8/1 16:52
     * @param shoot
     * @param enemyTank
     * player子弹击中Enemy(该方法只能在发射单颗子弹时可用)
    */
    public void hitEnemyTank(Shoot shoot, EnemyTank enemyTank) {
        //坦克左上顶点到右下顶点（+40，+60）or （+60，+40）
        switch (enemyTank.getDirection()) {
            case 0:
            case 2:

                //
                if (
                        (enemyTank.getX() <= shoot.getX()) && (shoot.getX() <= enemyTank.getX() + 40) &&
                                (enemyTank.getY() <= shoot.getY()) && (shoot.getY() <= enemyTank.getY() + 60)
//                               && enemyTank.isLive == true
                ) {
                    shoot.isLive = false;
                    enemyTank.isLive = false;
                    //从enemyTank中移除
                    enemyTanks.remove(enemyTank);

                    //被击中，创建Bomb对象，加入bombVectors
                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                    bombVectors.add(bomb);
                }
                break;
            case 1:
            case 4:
                if (
                        (enemyTank.getX() <= shoot.getX()) && (shoot.getX() <= enemyTank.getX() + 60) &&
                                (enemyTank.getY() <= shoot.getY()) && (shoot.getY() <= enemyTank.getY() + 40)
//                               && enemyTank.isLive == true
                ) {
                    shoot.isLive = false;
                    enemyTank.isLive = false;
                    //从enemyTank中移除
                    enemyTanks.remove(enemyTank);

                    //被击中，创建Bomb对象，加入bombVectors
                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                    bombVectors.add(bomb);
                }
                break;
        }

    }

    /**
    *
    * @author lihaonan
    * @date 2024/8/1 16:52
     * @param shoots
     * @param enemyTank
     * player发射多发子弹判断是否击中
    */
    public void hitEnemyTank_multi(Vector<Shoot> shoots, EnemyTank enemyTank) {

        for (int i = 0; i < shoots.size(); i++) {
            Shoot shoot = shoots.get(i);

            //坦克左上顶点到右下顶点（+40，+60）or （+60，+40）
            switch (enemyTank.getDirection()) {
                case 0:
                case 2:

                    //
                    if (
                            (enemyTank.getX() <= shoot.getX()) && (shoot.getX() <= enemyTank.getX() + 40) &&
                                    (enemyTank.getY() <= shoot.getY()) && (shoot.getY() <= enemyTank.getY() + 60)
//                               && enemyTank.isLive == true
                    ) {
                        shoot.isLive = false;
                        enemyTank.isLive = false;
                        //从enemyTank中移除
                        enemyTanks.remove(enemyTank);

                        //计数
                        Recorder.addCount();

                        //被击中，创建Bomb对象，加入bombVectors
                        Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                        bombVectors.add(bomb);
                    }
                    break;
                case 1:
                case 4:
                    if (
                            (enemyTank.getX() <= shoot.getX()) && (shoot.getX() <= enemyTank.getX() + 60) &&
                                    (enemyTank.getY() <= shoot.getY()) && (shoot.getY() <= enemyTank.getY() + 40)
//                               && enemyTank.isLive == true
                    ) {
                        shoot.isLive = false;
                        enemyTank.isLive = false;
                        //从enemyTank中移除
                        enemyTanks.remove(enemyTank);

                        //计数
                        Recorder.addCount();

                        //被击中，创建Bomb对象，加入bombVectors
                        Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                        bombVectors.add(bomb);
                    }
                    break;
            }
        }

    }

    public void hitPlayerTank_multi(Hero hero) {

        //先判断玩家坦克是否存活，只有存活才能被击中
        //把敌军的随机移动和随机方向禁用后测试
        if (hero.isLive) {
            for (int i = 0; i < enemyTanks.size(); i++) {
                Vector<Shoot> shoots = enemyTanks.get(i).shoots;
                for (int j = 0; j < shoots.size(); j++) {
                    Shoot shoot = shoots.get(j);
                    switch (hero.getDirection()) {
                        case 0:
                        case 2:

                            //
                            if (
                                    (hero.getX() <= shoot.getX()) && (shoot.getX() <= hero.getX() + 40) &&
                                            (hero.getY() <= shoot.getY()) && (shoot.getY() <= hero.getY() + 60)
//                               && enemyTank.isLive == true
                            ) {
                                shoot.isLive = false;
                                hero.isLive = false;

                                //保存时记录位置
                                heroes.remove(hero);

                                //被击中，创建Bomb对象，加入bombVectors
                                Bomb bomb = new Bomb(hero.getX(), hero.getY());
                                bombVectors.add(bomb);
                            }
                            break;
                        case 1:
                        case 4:
                            if (
                                    (hero.getX() <= shoot.getX()) && (shoot.getX() <= hero.getX() + 60) &&
                                            (hero.getY() <= shoot.getY()) && (shoot.getY() <= hero.getY() + 40)
//                               && enemyTank.isLive == true
                            ) {
                                shoot.isLive = false;
                                hero.isLive = false;

                                //保存时记录位置
                                heroes.remove(hero);

                                //被击中，创建Bomb对象，加入bombVectors
                                Bomb bomb = new Bomb(hero.getX(), hero.getY());
                                bombVectors.add(bomb);
                            }
                            break;
                    }
                }
            }
        }

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {

        //防止死后移动和发射子弹
        if (play2Hero != null && play2Hero.isLive) {
            //方向键
            if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                if (play2Hero.getX() - play2Hero.getSpeed() >= 0 ) {
                    play2Hero.moveLeft();
                }
            }
            if (e.getKeyCode() == KeyEvent.VK_UP) {
                if (play2Hero.getY() - play2Hero.getSpeed() >= 0 ) {
                    play2Hero.moveUp();
                }
            }
            if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                if (play2Hero.getY() + play2Hero.getSpeed() + 60 <= 750 ) {
                    play2Hero.moveDown();
                }

            }
            if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                if (play2Hero.getX() + play2Hero.getSpeed() + 60 <= 1000) {
                    play2Hero.moveRight();
                }
            }
            if (e.getKeyCode() == KeyEvent.VK_COMMA) {
                //player2没有子弹从才能射击
//            if (play2Hero.shoot == null || !play2Hero.shoot.isLive) {

                //限制屏幕上玩家最多发送5颗子弹
                if (play2Hero.shoot == null || play2Hero.shoots.size() < 5) {
                    play2Hero.shootEnemy();
                }
            }
        }

        //防止死后移动和发射子弹
        if (play1Hero != null && play1Hero.isLive) {
            //WASD
            switch (
                    e.getKeyCode()
            ) {
                case 87:
                    if (play1Hero.getY() - play1Hero.getSpeed() >= 0 ) {
                        play1Hero.moveUp();
                    }
                    break;
                case 65:
                    if (play1Hero.getX() - play1Hero.getSpeed() >= 0 ) {
                        play1Hero.moveLeft();
                    }
                    break;
                case 83:
                    if (play1Hero.getY() + play1Hero.getSpeed() + 60  < 750 ) {
                        play1Hero.moveDown();
                    }
                    break;
                case 68:
                    if (play1Hero.getX() + play1Hero.getSpeed() + 60 < 1000) {
                        play1Hero.moveRight();
                    }
                    break;
                case 74:
                    //发射子弹
                    //player1没有子弹从才能射击

                    //只能发射一颗子弹
//                if (play1Hero.shoot == null || !play1Hero.shoot.isLive) {
                    //限制屏幕上玩家最多发送5颗子弹
                    if (play1Hero.shoot == null || play1Hero.shoots.size() < 5) {
                        play1Hero.shootEnemy();
                    }
                    break;
            }
        }


        this.repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            if (play1Hero != null) {
                //player1发射子弹是否击中enemy
                if ( play1Hero.shoot!= null && play1Hero.shoot.isLive) {
                    System.out.println("play1Hero is " + play1Hero.toString());
                    for (int i = 0; i < enemyTanks.size(); i++) {
                        EnemyTank enemyTank = enemyTanks.get(i);

                        //只在玩家只能发送单颗子弹时使用
//                    hitEnemyTank(play1Hero.shoot, enemyTank);

                        hitEnemyTank_multi(play1Hero.shoots, enemyTank);
                    }
                }
                //敌军子弹是否击中player
                hitPlayerTank_multi(play1Hero);
            }

            if (play2Hero != null) {
                //player2发射子弹是否击中enemy
                if ( play2Hero.shoot!= null && play2Hero.shoot.isLive) {
                    for (int i = 0; i < enemyTanks.size(); i++) {
                        EnemyTank enemyTank = enemyTanks.get(i);
                        //只在玩家只能发送单颗子弹时使用
//                    hitEnemyTank(play2Hero.shoot, enemyTank);

                        hitEnemyTank_multi(play2Hero.shoots, enemyTank);
                    }
                }
                //敌军子弹是否击中player
                hitPlayerTank_multi(play2Hero);
            }

            this.repaint();
        }

    }
}
